package com.cqupt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cqupt.service.NetworkSearchService;
import com.cqupt.utils.APIUtils;
import com.cqupt.utils.XmlUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class NetworkSearchServiceImpl implements NetworkSearchService {


    /**
     * 创建动作自动注册Windows类型主机
     */
    @Override
    public void creatNetworkRuleForWindows() {

        //  设置条件
        List<Map<String, Object>> conditions = new ArrayList<>();
        conditions.add(new HashMap<String, Object>(){{
            put("conditiontype",24);
            put("operator",2);
            put("value","Windows");
        }});
        // 设置模板
        List<Map<String,String>> tamplates = new ArrayList<>();
        tamplates.add(new HashMap<String, String>(){{
            put("templateid","10081");
        }});
        // 设置操作
        List<Map<String, Object>> operations = new ArrayList<>();
        operations.add(new HashMap<String, Object>(){{
            put("operationtype",2);
        }});
        operations.add(new HashMap<String, Object>(){{
            put("operationtype",6);
            put("optemplate",tamplates);
        }});
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "action.create");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("name","Register Windows Servers");
                put("eventsource",2);
                put("status",0);
                put("filter",new HashMap<String,Object>(){{
                    put("evaltype",0);
                    put("conditions",conditions);
                }});
                put("operations",operations);
            }});

        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        System.out.println(responseMap);
    }

    /**
     * 创建动作自动注册Windows类型主机
     */
    @Override
    public void creatNetworkRuleForLinux() {
        //  设置条件
        List<Map<String, Object>> conditions = new ArrayList<>();
        conditions.add(new HashMap<String, Object>(){{
            put("conditiontype",24);
            put("operator",2);
            put("value","Linux");
        }});
        // 设置模板
        List<Map<String,String>> tamplates = new ArrayList<>();
        tamplates.add(new HashMap<String, String>(){{
            put("templateid","10001");
        }});
        // 设置操作
        List<Map<String, Object>> operations = new ArrayList<>();
        operations.add(new HashMap<String, Object>(){{
            put("operationtype",2);
        }});
        operations.add(new HashMap<String, Object>(){{
            put("operationtype",6);
            put("optemplate",tamplates);
        }});
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "action.create");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("name","Register Linux Servers");
                put("eventsource",2);
                put("status",0);
                put("filter",new HashMap<String,Object>(){{
                    put("evaltype",0);
                    put("conditions",conditions);
                }});
                put("operations",operations);
            }});

        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        System.out.println(responseMap);
    }

    //@Override
    // 根据IP段创建自动发现规则
    //public void creatNetworkRlueByIPRange(String iprange) {
    //    List<Map<String, Object>> dchecksList = new ArrayList<>();
    //    Map<String, Object> dcheck_agent = new HashMap<String, Object>(){{
    //        put("type","9");
    //        put("key_","system.uname");
    //        put("ports","10050");
    //        put("uniq","0");
    //    }};
    //    dchecksList.add(dcheck_agent);
    //    Map<String, Object> dcheck_hostname = new HashMap<String, Object>(){{
    //        put("type","9");
    //        put("key_","agent.hostname");
    //        put("ports","10050");
    //        put("uniq","0");
    //    }};
    //    dchecksList.add(dcheck_hostname);
    //    String token = APIUtils.getToken();
    //    Map<String, Object> paramsMap = new HashMap<String, Object>(){{
    //        put("auth",token);
    //        put("jsonrpc", "2.0");
    //        put("method", "drule.create");
    //        put("id", 1);
    //        put("params",new HashMap<String,Object>(){{
    //            put("name","Agent Discovery");
    //            // 例子--> IP段: 192.168.1-10.1-255. 范围受限于覆盖地址的总数（小于64K）
    //            put("iprange",iprange);
    //            put("dchecks",dchecksList);
    //            put("delay","1h");
    //        }});
    //    }};
    //    Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
    //    System.out.println(responseMap);
    //}

    /**
     * 新增发现规则
     * @param name 规则名称
     * @param iprange   规则ip段
     * @param type  规则类型（1:服务器类型，2：网络设备类型，3：PING类型）
     * @param SNMP_comminity    若是网络设备，对应网络社区号
     * @return
     */
    @Override
    public Map<String, Object> creatNetworkRlueByIPRange(String name,String iprange, String type, String SNMP_comminity) throws IllegalAccessException {
        List<Map<String, Object>> dchecksList = new ArrayList<>();
        if (type.equals("1")){
            Map<String, Object> dcheck_agent = new HashMap<String, Object>(){{
                // agent类型
                put("type","9");
                // 系统描述
                put("key_","system.uname");
                put("ports","10050");
                // 唯一
                put("uniq","0");
            }};
            dchecksList.add(dcheck_agent);
            Map<String, Object> dcheck_hostname = new HashMap<String, Object>(){{
                // agent类型
                put("type","9");
                //主机名称
                put("key_","agent.hostname");
                put("ports","10050");
                put("uniq","0");
            }};
            dchecksList.add(dcheck_hostname);
        }else if (type.equals("2")){
            String[] SNMP_comminity_list = SNMP_comminity.split(",");
            for (int i = 0; i < SNMP_comminity_list.length; i++) {
                int inner_i = i;
                Map<String, Object> dcheck_agent = new HashMap<String, Object>(){{
                    put("type","11");
                    // 社区号
                    put("snmp_community",SNMP_comminity_list[inner_i]);
                    put("ports","161");
                    // 获取主机名
                    put("key_",".1.3.6.1.2.1.1.5.0");
                    put("uniq","0");
                }};
                dchecksList.add(dcheck_agent);
                Map<String, Object> dcheck_des = new HashMap<String, Object>(){{
                    put("type","11");
                    // 社区号
                    put("snmp_community",SNMP_comminity_list[inner_i]);
                    put("ports","161");
                    // 获取描述
                    put("key_",".1.3.6.1.2.1.1.1.0");
                    put("uniq","0");
                }};
                dchecksList.add(dcheck_des);
            }
        }else if(type.equals("3")){
            Map<String, Object> dcheck_ping = new HashMap<String, Object>(){{
                put("type","12");
                put("uniq","0");
            }};
            dchecksList.add(dcheck_ping);
        }
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "drule.create");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("name",name);
                // 例子--> IP段: 192.168.1-10.1-255. 范围受限于覆盖地址的总数（小于64K）
                put("iprange",iprange);
                put("dchecks",dchecksList);
                put("delay","1h");
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        if (responseMap.get("result") != null){
            return new HashMap<String, Object>(){{
                put("status",true);
            }};
        }else {
            HashMap<String, Object> retMap = new HashMap<>();
            retMap.put("status", false);
            retMap.put("error_code", "ip参数错误，请重新填写。");
            return retMap;
        }
    }

    /**
     * 根据ID删除网络发现规则
     * @param ids
     */
    @Override
    public void deleteNetworkRlueByIDs(List<String> ids) {
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "drule.delete");
            put("id", 1);
            put("params",ids);
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        System.out.println(responseMap);
    }

    /**
     * 根据ID删除网络发现规则
     * @param id 网络发现规则id
     * @return 删除成功为true,失败为false
     */
    @Override
    public boolean deleteNetworkRlueByID(String id) {
        String[] idList = new String[]{id};
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "drule.delete");
            put("id", 1);
            put("params",idList);
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        if (responseMap.get("result") != null){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 修改网络发现规则
     * @param id 网络发现规则id
     * @param iprange 网络发现规则ip段
     * @return
     */
    @Override
    public boolean updateNetworkRlueByIPRange(String id, String iprange) {
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "drule.delete");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("druleid",id);
                put("iprange",iprange);
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        //System.out.println(responseMap);
        if (responseMap.get("result") != null){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 修改规则(SNMP)
     * @param id 网络发现规则id
     * @param iprange 网络发现规则ip段
     * @param SNMP_comminity 网络发现规则社区列表
     * @return
     */
    @Override
    public boolean updateNetworkRlueByIPRangeForSNMP(String id, String iprange, String SNMP_comminity) {
        return false;
    }

    /**
     * 搜索所有自动发现规则创建的主机设备
     * @param ruleClass 自动发现类别对应的主机
     * @param ipSet 集合包含不同的ip
     * @return
     */
    @Override
    public List<Map<String, Object>> serachAllNetRuleAgents(Map<String, Object> ruleClass, Set<String> ipSet) {
        // 发现主机设备总数
        int count = 0;
        String token = APIUtils.getToken();
        // 返回结果属性过滤
        String[] outputs = new String[]{"druleid"};
        // 发现服务过滤
        String[] selectDServices = new String[]{"ip","value","dcheckid"};
        // 发现规则状态过滤
        String[] selectDRules = new String[]{"status"};
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "dhost.get");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("output",outputs);
                put("selectDServices",selectDServices);
                put("selectDRules",selectDRules);
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resList = (List<Map<String, Object>>) responseMap.get("result");
        List<Map<String, Object>> checkList = (List<Map<String, Object>>) ruleClass.get("checkList");
        List<Map<String, Object>> resAgents = new ArrayList<>();
        // 遍历发现主机列表
        for (int i = 0; i < resList.size(); i++) {
            Map<String, Object> tempMap = new HashMap<>();
            // 发现规则id
            String druleid = (String) resList.get(i).get("druleid");
            // 获取所有的发现规则列表
            List<Map<String,Object>> drules = (List<Map<String, Object>>) resList.get(i).get("drules");
            // 若规则状态为启用
            if (drules.get(0).get("status").equals("0")){
                // 当前规则属于Zabbix发现规则
                if (((ArrayList<String>)ruleClass.get("agentRuleIdList")).contains(druleid)){
                    tempMap.put("druleid",druleid);
                    List<Map<String, Object>> dservices = (List<Map<String, Object>>) resList.get(i).get("dservices");
                    tempMap.put("ip",dservices.get(0).get("ip"));
                    // 当前发现主机是否在线
                    if (ipSet.contains(dservices.get(0).get("ip"))){
                        tempMap.put("hostStatus","false");
                    }else {
                        tempMap.put("hostStatus","true");
                    }
                    // 对发现主机类别分类
                    if (dservices.size() > 0){
                        // 检查服务中第一个值包含主机类别信息
                        if (dservices.get(0).get("value").toString().contains("Windows")){
                            tempMap.put("sysType","Windows");
                        }else if (dservices.get(0).get("value").toString().contains("Linux")){
                            tempMap.put("sysType","Linux");
                        }
                        // 检查服务第二个值包含主机名称信息
                        if (dservices.size() > 1){
                            tempMap.put("hostName",dservices.get(1).get("value"));
                        }else {
                            tempMap.put("hostName","暂未发现主机名");
                        }
                    }else {
                        tempMap.put("sysType","暂未发现类型");
                        tempMap.put("hostName","暂未发现主机名");
                    }
                }else if(((ArrayList<String>)ruleClass.get("SNMPRuleIdList")).contains(druleid)){
                    //当前主机属于SNMP设备
                    tempMap.put("druleid",druleid);
                    List<Map<String, Object>> dservices = (List<Map<String, Object>>) resList.get(i).get("dservices");
                    tempMap.put("ip",dservices.get(0).get("ip"));
                    if (ipSet.contains(dservices.get(0).get("ip"))){
                        tempMap.put("hostStatus","false");
                    }else {
                        tempMap.put("hostStatus","true");
                    }
                    tempMap.put("sysType","SNMP");
                    Map<String, Object> checkDetails = checkList.get(count++);
                    List<String> checkids = (List<String>) checkDetails.get("checkids");
                    List<String> Communitys = (List<String>) checkDetails.get("Community");
                    // 对发现主机的服务进行遍历
                    for (int j = 0; j < dservices.size(); j++) {
                        if (!dservices.get(j).get("value").equals("") && checkids.contains((String) dservices.get(j).get("dcheckid"))){
                            int index = checkids.indexOf((String) dservices.get(j).get("dcheckid"));
                            tempMap.put("snmpCommunity",Communitys.get(index));
                        }
                    }
                    //检查服务数量大于2
                    if (dservices.size() >= 2){
                        int key = 0;
                        while(dservices.get(key).get("value").equals("")){
                            key = key + 2;
                        }
                        tempMap.put("hostName",dservices.get(key).get("value"));
                    }else {
                        tempMap.put("hostName","暂未发现主机名");
                    }
                }else if (((ArrayList<String>)ruleClass.get("ICMPpingList")).contains(druleid)){
                    // 主机检查类型属于ICMP类型
                    tempMap.put("druleid",druleid);
                    List<Map<String, Object>> dservices = (List<Map<String, Object>>) resList.get(i).get("dservices");
                    tempMap.put("ip",dservices.get(0).get("ip"));
                    // 在线主机的ip中是否包括当前服务ip
                    if (ipSet.contains(dservices.get(0).get("ip"))){
                        tempMap.put("hostStatus","false");
                    }else {
                        tempMap.put("hostStatus","true");
                    }
                    // 类型为icmp
                    tempMap.put("sysType","icmp");
                    if (dservices.size() == 1){
                        tempMap.put("hostName",dservices.get(0).get("ip"));
                    }
                }
                resAgents.add(tempMap);
            }
        }
        return resAgents;
    }

    /**
     * 搜索所有自动发现规则创建的主机设备
     * @return
     */
    @Override
    public Map<String, Object> serachAllNetRule() {
        String token = APIUtils.getToken();
        // 过滤返回的属性
        String[] outputs = new String[]{"druleid"};
        // 过滤获得的自动发现规则检查属性{"type","snmp_community","dcheckid"}
        String[] selectDChecks = new String[]{"type","snmp_community","dcheckid"};
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            // 发现规则获取方法
            put("method", "drule.get");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("output",outputs);
                put("selectDChecks",selectDChecks);
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resList = (List<Map<String, Object>>) responseMap.get("result");
        Map<String, Object> resRulesClass = new HashMap<>();
        List<String> agentRuleIdList = new ArrayList<>();
        List<String> SNMPRuleIdList = new ArrayList<>();
        List<String> snmpCommunityList = new ArrayList<>();
        List<Map<String, Object>> checkList = new ArrayList<>();
        List<String> ICMPpingList = new ArrayList<>();
        // 遍历所有发现主机，并进行分类
        for (int i = 0; i < resList.size(); i++) {
            // 社区信息列表
            List<String> snmpCommunityDetailslist = new ArrayList<>();
            // 检查规则列表
            List<String> dcheckidList = new ArrayList<>();
            // 当前发现规则id
            String druleId = (String) resList.get(i).get("druleid");
            // 当前发现规则检查列表
            List<Map<String, Object>> dchecks = (List<Map<String, Object>>) resList.get(i).get("dchecks");
            // 第一个检查规则的种类
            String type = (String) dchecks.get(0).get("type");
            // 社区集合
            Set<String> snmpCommunity_set = new HashSet<>();
            // 遍历每个发现检查（一个检查可包含多个社区信息）
            for (int j = 0; j < dchecks.size() && !((String) dchecks.get(j).get("snmp_community")).equals(""); j++) {
                // 获取snmp_community属性
                String tempSnmpCommunity = (String) dchecks.get(j).get("snmp_community");
                // 获取dcheckid属性
                String tempDCheckid = (String) dchecks.get(j).get("dcheckid");
                // 添加进snmpCommunity_set中
                if (!snmpCommunity_set.contains(tempSnmpCommunity)){
                    snmpCommunityDetailslist.add(tempSnmpCommunity);
                    snmpCommunity_set.add(tempSnmpCommunity);
                    dcheckidList.add(tempDCheckid);
                }
            }
            // 若种类id为 ‘9’，代表 Zabbix 客户端
            if (type.equals("9")){
                agentRuleIdList.add(druleId);
            }else if (type.equals("11")){
                // 若种类id为 ‘11’，代表  SNMPv2 客户端
                SNMPRuleIdList.add(druleId);
                Map checkMap = new HashMap();
                checkMap.put("Community",snmpCommunityDetailslist);
                checkMap.put("checkids",dcheckidList);
                checkList.add(checkMap);
            }else if (type.equals("12")){
                // 若种类id为 ‘11’，代表  ICMP ping 客户端
                ICMPpingList.add(druleId);
            }
        }
        resRulesClass.put("agentRuleIdList",agentRuleIdList);
        resRulesClass.put("SNMPRuleIdList",SNMPRuleIdList);
        resRulesClass.put("ICMPpingList",ICMPpingList);
        resRulesClass.put("checkList",checkList);
        return resRulesClass;
    }

    /**
     * 获取所有自动发现规则详情
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllNetRuleDetails() {
        // 获取令牌
        String token = APIUtils.getToken();
        // 输出结果进行过滤
        String[] outputs = new String[]{"druleid","iprange","delay","name","status"};
        // 发现规则进行过滤
        String[] selectDChecks = new String[]{"type","snmp_community"};
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "drule.get");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("output",outputs);
                put("selectDChecks",selectDChecks);
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resList = (List<Map<String, Object>>) responseMap.get("result");
        List<Map<String, Object>> resRulesList = new ArrayList<>();
        // 遍历结果，并对每个发现规则进行分类（服务器：9，网络设备：11，ICMP:12）
        for (int i = 0; i < resList.size(); i++) {
            Map<String, Object> curMap = new HashMap<>();
                curMap.put("details",resList.get(i));
                if (((List<Map<String, Object>>)resList.get(i).get("dchecks")).get(0).get("type").equals("9")){
                    curMap.put("type", "服务器");
                }else if (((List<Map<String, Object>>)resList.get(i).get("dchecks")).get(0).get("type").equals("11")){
                    curMap.put("type", "网络设备");
                }else if (((List<Map<String, Object>>)resList.get(i).get("dchecks")).get(0).get("type").equals("12")){
                    curMap.put("type", "ICMP Ping");
                }
            resRulesList.add(curMap);
        }

        return resRulesList;
    }

    /**
     * 修改网络发现规则
     * @param id
     * @param status
     * @return
     */
    @Override
    public boolean updateNetworkRuleStatus(String id, String status) {
        String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>(){{
            put("auth",token);
            put("jsonrpc", "2.0");
            put("method", "drule.update");
            put("id", 1);
            put("params",new HashMap<String,Object>(){{
                put("druleid",id);
                put("status",status);
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        if (responseMap.get("result") != null){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 获取所有发现主机状态
     * @return
     */
    @Override
    public Map<String, Object> getAllNetworkRuleNumAndStatus() {


        return null;
    }

    /**
     * 从配置文件中读取community配置
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllSNMPCommunityByXML() {
        // 工具类中读取配置文件信息
        List<Map<String, Object>> communityByXML = XmlUtils.analysisXMLCommunity();
        return communityByXML;
    }
}
